﻿using System;
using System.Xml;
using BasecampRestAPI;
using NUnit.Framework;
using TestBasecampRestAPI.Fakes;
using TestBasecampRestAPI.TestMoveToDoList;

namespace TestBasecampRestAPI
{
	[TestFixture]
	public class TestToDoListItem
	{
		FakeBaseCamp _camp;
		FakeRestWebService _service;
		IToDoListItem _item;

		[SetUp]
		public void SetUp()
		{
			_camp = FakeBaseCamp.GetInstance();
			_service = FakeRestWebService.GetInstance();
			_camp.ServiceGetFakeResult = _service;
			_item = ToDoListItem.GetInstance(_camp, GetElementForXml(Properties.Resources.FakeToDoItem));
		}

		[Test]
		public void Construct()
		{
			Assert.IsNotNull(_item);
			Assert.AreEqual(1601, _item.Id);
			Assert.AreEqual("This is the first ToDo item.", _item.Content);
			Assert.AreEqual(1, _item.Position);
			Assert.AreEqual(new DateTime(1969, 12, 03, 16, 45, 45), _item.CreatedOn);
			Assert.AreEqual(true, _item.Completed);
			Assert.AreEqual(2, _item.CommentsCount);
			Assert.AreEqual("Company", _item.ResponsiblePartyType);
			Assert.AreEqual(new DateTime(1977, 12, 03, 16, 45, 45), _item.CompletedOn);
		}

		[Test]
		public void Creator()
		{
			FakePerson person = new FakePerson();
			_camp.GetPersonByIdFakeResult = person;
			IPerson result = _item.Creator;
			Assert.IsNotNull(result);
			Assert.AreEqual(person, result);
		}

		[Test]
		public void AddComment()
		{
			_service.PostRequestGetLocationFakeResult = "/comments/987.xml";
			ConfigureResponseXml(Properties.Resources.FakeComment);
			const string body = "This is a comment on another resource.";
			IComment comment = _item.AddComment(body);
			Assert.IsNotNull(comment);
			Assert.AreEqual(987, comment.Id);
			Assert.AreEqual(body, comment.Body);
		}

		[Test]
		public void AddTimeEntry()
		{
			FakePerson person = new FakePerson { Id = 222 };
			DateTime date = new DateTime(2009, 12, 03);
			const double hours = 4.5;
			const string description = "I did some stuff.";
			const string location = "/time_entries/8787.xml";
			_service.PostRequestGetLocationFakeResult = location;
			ConfigureResponseXml(Properties.Resources.FakeTimeEntry);
			ITimeEntry entry = _item.AddTimeEntry(person, date, hours, description);
			Assert.IsNotNull(entry);
			Assert.AreEqual(date, entry.Date);
			Assert.AreEqual(hours, entry.Hours);
			Assert.AreEqual(description, entry.Description);
		}

		[Test]
		public void Complete()
		{
			ConfigureResponseXml("<result/>");
			_item.Complete();
			Assert.IsTrue(_service.PutRequestCalled);
			Assert.AreEqual(string.Format("todo_items/{0}/complete.xml", 1601), _service.PutRequestLastRequestPath);
		}

		[Test]
		public void Comments()
		{
			IComment fakeComment1 = new FakeComment { Id = 1414 };
			IComment fakeComment2 = new FakeComment { Id = 1415 };
			IComment[] fakeComments = new IComment[] { fakeComment1, fakeComment2 };
			_camp.CommentsForResourceFakeResult = fakeComments;
			IComment[] comments = _item.RecentComments;
			Assert.AreEqual(comments.Length, _item.CommentsCount);
			Assert.AreEqual(fakeComment1.Id, comments[0].Id);
			Assert.AreEqual(fakeComment2.Id, comments[1].Id);
		}

		private void ConfigureResponseXml(string xml)
		{
			_service.GetRequestResponseElementFakeResult = TestBasecamp.GetElementForXml(xml);
		}

		private static XmlNode GetElementForXml(string xml)
		{
			return TestBasecamp.GetElementForXml(xml);
		}
	}
}
